
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.brain.sgc.view.mbean;

import com.brain.core.view.mbean.*;
import com.brain.core.common.UtilCore;
import com.brain.core.dto.ParametroDto;
import com.brain.core.exception.DAOException;
import com.brain.core.manager.RecursosManager;
import com.brain.sgc.dto.EvaluacionDto;
import com.brain.sgc.dto.ProcesoEvaluacionDto;
import com.brain.sgc.dto.ProcesoSGCDto;
import com.brain.sgc.manager.EvaluacionManager;
import com.brain.sgc.manager.ProcesoEvaluacionManager;
import com.brain.sgc.manager.ProcesoSGCManager;
import com.brain.sgc.view.util.ConstantesSgc;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

/**
 *
 * @author Hvives
 */
@Controller("procesoSGCMBean")
@Scope("session")
public class ProcesoSGCMBean extends GenericMBean implements Serializable {

    /**
     * Guarda las acciones del sistema en un archivo de texto plano
     *
     * @since 29/01/2014
     */
    private static Logger logger = Logger.getLogger(ProcesoSGCMBean.class);
    /**
     * objeto de la clase ProcesoSGCManager
     *
     * @since 29/01/2014
     */
    @Resource
    private ProcesoSGCManager manager;

    @Resource
    private RecursosManager recursosManager;
    /**
     * objeto de la clase ProcesoEvaluacionManager
     *
     * @since 29/01/2014
     */
    @Resource
    private ProcesoEvaluacionManager procesoEvalManager;
    /**
     * objeto de la clase EvaluacionManager
     *
     * @since 29/01/2014
     */
    @Resource
    private EvaluacionManager evaluacionManager;
    /**
     * objeto de la clase ProcesoEvaluacionDto
     *
     * @since 29/01/2014
     */
    private ProcesoEvaluacionDto procesoEvaluacionDto;
    /**
     * objeto tipo lista de la clase ProcesoSGCDto
     *
     * @since 29/01/2014
     */
    private List<ProcesoSGCDto> lista;
    /**
     * objeto de la entidad actual
     *
     * @since 29/01/2014
     */
    private ProcesoSGCDto dto;
    /**
     * objeto de la entidad actual
     *
     * @since 29/01/2014
     */
    private ProcesoSGCDto dtoFiltro;
    /**
     * Titulo del formulario
     *
     * @since 29/01/2014
     */
    private String keyTitulo = "proceso.panel";
    /**
     * objeto de la clase ApplicationMBean , acceso a la clase utilitaria de
     * configuración
     *
     * @since 29/01/2014
     */
    @Autowired
    private ApplicationMBean applicationMBean;
    /**
     * objeto de la clase SessionMBean
     *
     * @since 29/01/2014
     */
    @Autowired
    private SessionMBean sessionMBean;
    /**
     * objeto tipo array de la clase SelectItem
     *
     * @since 29/01/2014
     */
    private SelectItem[] siRequerimientoPrioridad;
    /**
     * objeto tipo array de la clase SelectItem
     *
     * @since 29/01/2014
     */
    private SelectItem[] siTipoProceso;
    /**
     * objeto tipo lista de la clase ParametroDto
     *
     * @since 29/01/2014
     */
    private List<ParametroDto> listaEstadosRequerimiento;
    private List<ParametroDto> listaSedesFiltro;
    private List<ParametroDto> listaSedesNuevo;
    private List<ParametroDto> listaModContratacion;
    private List<EvaluacionDto> listaEvaluaciones;
    /**
     * objeto tipo lista de la clase ProcesoEvaluacionDto
     *
     * @since 29/01/2014
     */
    private List<ProcesoEvaluacionDto> listaProcesoEvaluacionAux;
    /**
     * Valores Booleanos que indica el estado de la visibilidad de los botones
     * del formulario
     *
     * @since 29/01/2014
     */
    private boolean accesoAnular;
    private boolean accesoAprobar;
    private boolean accesoRechazar;
    private boolean accesoGuardar;
    /**
     * objeto tipo array de la clase EvaluacionDto
     *
     * @since 29/01/2014
     */
    private EvaluacionDto[] selectedEvals;
    private Long indeice;
    private boolean habilitarEvaluacion = false;

    /**
     * Metodo constructor de la clase
     *
     * @since 29/01/2014
     */
    public ProcesoSGCMBean() {
        this.dtoFiltro = new ProcesoSGCDto();
    }

    /**
     * Metodo que permite instanciar todos los objetos al iniciar el formulario
     *
     * @since 29/01/2014
     */
    public String iniciar() {
        this.dto = null;
        this.lista = null;
        this.dtoFiltro = new ProcesoSGCDto();
        this.dtoFiltro.setEstado(Boolean.TRUE);
        return ConstantesSgc.UrlNavegacion.URL_LISTA_PROCESO;
    }

    /**
     * Metodo que setea los valores del dto y construye el formulario para crear
     * un nuevo registro
     *
     * @since 29/01/2014
     * @return retorna la url de la nueva pagina
     */
    public String nuevo() {
        sessionMBean.setAccion(ConstantesSgc.Formulario.NUEVO);
        sessionMBean.setTitulo(recursosManager.construirTitulo(keyTitulo, sessionMBean.getAccion()));
        this.lista = new ArrayList<ProcesoSGCDto>();
        this.dto = manager.inicializar();
        return ConstantesSgc.UrlNavegacion.URL_PROCESO;
    }

    /**
     * Metodo que permite cargar los valores de un dto existente y construye el
     * formulario para editar un registro
     *
     * @since 29/01/2014
     * @return retorna la url de la pagina de editado
     */
    public String editar() {
        sessionMBean.setAccion(ConstantesSgc.Formulario.EDITAR);
        sessionMBean.setTitulo(recursosManager.construirTitulo(keyTitulo, sessionMBean.getAccion()));
        //ApplicationHelper.cargarPropietarios(ConstantesSgc.Entidad.REQUERIMIENTO, this.dto.getId());
        this.listaProcesoEvaluacionAux = this.dto.getListaProcesoEvaluacion();
        return ConstantesSgc.UrlNavegacion.URL_PROCESO;
    }

    /**
     * Metodo que permite ver los datos existentes de un dto , sin opción a
     * editar o modificar algún valor
     *
     * @since 29/01/2014
     * @return retorna la url de la pagina principal del formulario
     */
    public String ver() {
        sessionMBean.setAccion(ConstantesSgc.Formulario.VER);
        sessionMBean.setTitulo(recursosManager.construirTitulo(keyTitulo, sessionMBean.getAccion()));
        //ApplicationHelper.cargarPropietarios(ConstantesSgc.Entidad.REQUERIMIENTO, this.dto.getId());
        return ConstantesSgc.UrlNavegacion.URL_PROCESO;
    }

    /**
     * Metodo que permite validar el cargado de un popup
     *
     * @since 29/01/2014
     */
    public void cargarPopupEvaluacion() {
        try {
            this.listaEvaluaciones = this.evaluacionManager.obtenerEvaluacionesActivas();
            this.quitarEvaluacionesYaSeleccionadas();
        } catch (Exception ex) {
            logger.error("ERROR DE SISTEMA", ex);
            showError(ex.getMessage());
        }
    }

    /**
     * Metodo que permite habilitar y deshabilidad evaluaciones
     *
     * @since 29/01/2014
     */
    protected void quitarEvaluacionesYaSeleccionadas() {
        List<EvaluacionDto> l = new ArrayList<EvaluacionDto>();
        for (EvaluacionDto e : this.listaEvaluaciones) {
            Boolean i = true;
            for (ProcesoEvaluacionDto pe : this.listaProcesoEvaluacionAux) {
                if (e.getId().equals(pe.getEvaluacionDto().getId())) {
                    i = false;
                }
            }
            if (i) {
                l.add(e);
            }
        }

        if (l.isEmpty()) {
            System.out.print(l.size());
            this.habilitarEvaluacion = true;
        } else {
            this.habilitarEvaluacion = false;
        }

        this.listaEvaluaciones = l;
    }

    /**
     * Metodo que permite agregar un proceso de evaluacion a la entidad actual
     *
     * @since 29/01/2014
     */
    public void agregarProcesoEvaluacion() {
        ProcesoEvaluacionDto dtoAux;
        for (EvaluacionDto x : this.selectedEvals) {
            if (validarEvaluacion(x.getId())) {
                dtoAux = new ProcesoEvaluacionDto();
                dtoAux.setUsuarioCreacion(sessionMBean.getSessionUsuarioDto().getId());
                dtoAux.setFechaCreacion(UtilCore.Fecha.obtenerFechaActualDate());
                dtoAux.setTerminalCreacion(sessionMBean.getSessionTerminal());
                dtoAux.setEvaluacionDto(x);
                dtoAux.setProcesoDto(this.dto);
                dtoAux.setPorcentaje(x.getPorcentaje());
                dtoAux.setOrden(x.getOrden());
                this.listaProcesoEvaluacionAux.add(dtoAux);
            }
        }
        selectedEvals = null;
    }

    /**
     * Metodo que permite validad una evaluacion
     *
     * @since 29/01/2014
     * @param x valor que se envia para evaluar
     * @return retorna un valor booleano que indica si los datos son correctos
     */
    public Boolean validarEvaluacion(Long x) {
        Boolean variable = true;
        try {
            for (int i = 0; i < this.dto.getListaProcesoEvaluacion().size(); i++) {
                if (this.dto.getListaProcesoEvaluacion().get(i).getId() != null) {
                    if (this.dto.getListaProcesoEvaluacion().get(i).getEvaluacionDto().getId().equals(x)) {
                        variable = false;
                    }
                } else {
                    if (this.dto.getListaProcesoEvaluacion().get(i).getEvaluacionDto().getId().equals(x)) {
                        variable = false;
                    }
                }
            }

        } catch (Exception ex) {
            logger.error("ERROR DE SISTEMA", ex);
            showError(ex.getMessage());
        }
        return variable;
    }

    /**
     * Metodo que permite eliminar registros de evaluaciones seleccionados
     *
     * @since 29/01/2014
     */
    public void eliminarReqEvaluacion() {
        try {
            if (this.procesoEvaluacionDto.getId() != null) {
                this.procesoEvalManager.eliminar(this.procesoEvaluacionDto);
            }
            this.listaProcesoEvaluacionAux.remove(this.procesoEvaluacionDto);

            showMessage(UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok"));
        } catch (Exception ex) {
            logger.error("ERROR DE SISTEMA", ex);
            showError(ex.getMessage());
        }
    }

    /**
     * Metodo que permite obtener el index de la lista de evaluaciones
     * seleccionados
     *
     * @since 29/01/2014
     */
    public void eliminarReqEvaluacionIndex() {
        this.listaProcesoEvaluacionAux.remove(indeice.intValue());
    }

    /**
     * Metodo que permite buscar todos los registros de la entidad actual
     *
     * @param ae evento que se lanza al ejecutar una acción
     * @since 29/01/2014
     */
    public void buscar(ActionEvent ae) {
        try {
            this.lista = this.manager.obtenerProcesos(this.dtoFiltro);
        } catch (DAOException ex) {
            logger.error("ERROR DE SISTEMA", ex);
            showError(ex.getMessage());
        }

    }

    /**
     * Metodo que permite guardar valores de la entidad actual
     *
     * @since 29/01/2014
     * @return retorna un valor nulo
     */
    public String guardar() {
        if (this.manager.guardar(this.dto) != null) {
            return "";
        }
        return "";
    }

    /**
     * Metodo que permite guardar el proceso de una evaluacion
     *
     * @since 29/01/2014
     */
    public void guardarProcesoEvaluacion() {
        try {
            List<ProcesoEvaluacionDto> listaProEval = new ArrayList<ProcesoEvaluacionDto>();
            ProcesoEvaluacionDto dtoAux;
            double porcentajeValido = validarPorcentaje();
            if (porcentajeValido > 0) {
                if (validarOrden()) {
                    double peso = 0;
                    for (ProcesoEvaluacionDto x : this.listaProcesoEvaluacionAux) {
                        if (x.getId() == null) {
                            dtoAux = new ProcesoEvaluacionDto();
                            dtoAux.setUsuarioCreacion(sessionMBean.getSessionUsuarioDto().getId());
                            dtoAux.setFechaCreacion(UtilCore.Fecha.obtenerFechaActualDate());
                            dtoAux.setTerminalCreacion(sessionMBean.getSessionTerminal());
                            dtoAux.setProcesoDto(this.dto);
                            dtoAux.setEvaluacionDto(x.getEvaluacionDto());
                            dtoAux.setPorcentaje(x.getPorcentaje());
                            dtoAux.setOrden(x.getOrden());
                            dtoAux.setEstado(Boolean.TRUE);
                            listaProEval.add(dtoAux);

                        } else {
                            this.procesoEvalManager.editar(x);
                        }
                        peso += x.getPorcentaje().doubleValue();
                    }
                    //Actualizamos el peso en el proceso
                    this.dto.setPeso(UtilCore.Numero.round(BigDecimal.valueOf(peso), 2));
                    this.manager.editar(this.dto);
                    this.procesoEvalManager.nuevoMuchos(listaProEval);
                    showMessage(UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok"));
                } else {
                    showError(UtilCore.Internacionalizacion.getMensajeInternacional("evaluacion.label.orden.validacion"));
                }
            } else {
                showError(UtilCore.Internacionalizacion.getMensajeInternacional("evaluacion.label.porcentaje.validacion"));
            }
            this.dto = this.manager.obtenerPorId(this.dto.getId());
        } catch (Exception ex) {
            logger.error("ERROR DE SISTEMA", ex);
            showError(ex.getMessage());
        }
    }

    /**
     * Metodo que permite validar el porcentaje
     *
     * @since 29/01/2014
     * @return retorna un valor de porcentaje valido
     */
    public double validarPorcentaje() {
        double porcentajeValido = 0;
        for (ProcesoEvaluacionDto x : this.listaProcesoEvaluacionAux) {
            double valor = Double.parseDouble(x.getPorcentaje().toString());
            porcentajeValido += valor;
        }
        return porcentajeValido;
    }

    /**
     * Metodo que permite validar el orden de una lista de proceso de evaluacion
     *
     * @since 29/01/2014
     * @return retorna un valor booleano de confirmacion
     */
    public Boolean validarOrden() {
        double porcentaje = 0;
        for (ProcesoEvaluacionDto x : this.listaProcesoEvaluacionAux) {
            porcentaje += x.getPorcentaje().doubleValue();
            if (x.getOrden() > 0L && x.getOrden() <= this.listaProcesoEvaluacionAux.size()) {
                for (ProcesoEvaluacionDto x1 : this.listaProcesoEvaluacionAux) {
                    if (x.getOrden().equals(x1.getOrden()) && !x.getEvaluacionDto().getId().equals(x1.getEvaluacionDto().getId())) {
                        return false;
                    }
                }
            } else {
                return false;
            }
        }
        if (BigDecimal.valueOf(porcentaje).compareTo(BigDecimal.valueOf(100)) > 0) {
            return false;
        }
        return true;
    }

    /**
     * Metodo que permite retroceder , del formulario actual . A la lista de
     * búsqueda
     *
     * @since 29/01/2014
     * @return retorna la url de la pagina de busqueda de entidad actual
     */
    public String retroceder() {
        buscar(null);
        sessionMBean.setAccion(ConstantesSgc.Formulario.LISTA);
        sessionMBean().setTitulo(recursosManager.construirTitulo(keyTitulo, sessionMBean().getAccion()));
        return ConstantesSgc.UrlNavegacion.URL_LISTA_PROCESO;
    }

    public static Logger getLogger() {
        return logger;
    }

    public static void setLogger(Logger logger) {
        ProcesoSGCMBean.logger = logger;
    }

    public ProcesoSGCManager getManager() {
        return manager;
    }

    public void setManager(ProcesoSGCManager manager) {
        this.manager = manager;
    }

    public RecursosManager getRecursosManager() {
        return recursosManager;
    }

    public void setRecursosManager(RecursosManager recursosManager) {
        this.recursosManager = recursosManager;
    }

    public List<ProcesoSGCDto> getLista() {
        return lista;
    }

    public void setLista(List<ProcesoSGCDto> lista) {
        this.lista = lista;
    }

    public ProcesoSGCDto getDto() {
        return dto;
    }

    public void setDto(ProcesoSGCDto dto) {
        this.dto = dto;
    }

    public ProcesoSGCDto getDtoFiltro() {
        return dtoFiltro;
    }

    public void setDtoFiltro(ProcesoSGCDto dtoFiltro) {
        this.dtoFiltro = dtoFiltro;
    }

    public String getKeyTitulo() {
        return keyTitulo;
    }

    public void setKeyTitulo(String keyTitulo) {
        this.keyTitulo = keyTitulo;
    }

    public ApplicationMBean getApplicationMBean() {
        return applicationMBean;
    }

    public void setApplicationMBean(ApplicationMBean applicationMBean) {
        this.applicationMBean = applicationMBean;
    }

    public SessionMBean getSessionMBean() {
        return sessionMBean;
    }

    public void setSessionMBean(SessionMBean sessionMBean) {
        this.sessionMBean = sessionMBean;
    }

    public List<ParametroDto> getListaEstadosRequerimiento() {
        return listaEstadosRequerimiento;
    }

    public void setListaEstadosRequerimiento(List<ParametroDto> listaEstadosRequerimiento) {
        this.listaEstadosRequerimiento = listaEstadosRequerimiento;
    }

    public List<ParametroDto> getListaSedesFiltro() {
        return listaSedesFiltro;
    }

    public void setListaSedesFiltro(List<ParametroDto> listaSedesFiltro) {
        this.listaSedesFiltro = listaSedesFiltro;
    }

    public List<ParametroDto> getListaSedesNuevo() {
        return listaSedesNuevo;
    }

    public void setListaSedesNuevo(List<ParametroDto> listaSedesNuevo) {
        this.listaSedesNuevo = listaSedesNuevo;
    }

    public List<ParametroDto> getListaModContratacion() {
        return listaModContratacion;
    }

    public void setListaModContratacion(List<ParametroDto> listaModContratacion) {
        this.listaModContratacion = listaModContratacion;
    }

    public SelectItem[] getSiRequerimientoPrioridad() {
        return siRequerimientoPrioridad;
    }

    public void setSiRequerimientoPrioridad(SelectItem[] siRequerimientoPrioridad) {
        this.siRequerimientoPrioridad = siRequerimientoPrioridad;
    }

    public boolean isAccesoAnular() {
        return accesoAnular;
    }

    public void setAccesoAnular(boolean accesoAnular) {
        this.accesoAnular = accesoAnular;
    }

    public boolean isAccesoAprobar() {
        return accesoAprobar;
    }

    public void setAccesoAprobar(boolean accesoAprobar) {
        this.accesoAprobar = accesoAprobar;
    }

    public boolean isAccesoRechazar() {
        return accesoRechazar;
    }

    public void setAccesoRechazar(boolean accesoRechazar) {
        this.accesoRechazar = accesoRechazar;
    }

    public boolean isAccesoGuardar() {
        return accesoGuardar;
    }

    public void setAccesoGuardar(boolean accesoGuardar) {
        this.accesoGuardar = accesoGuardar;
    }

    public EvaluacionDto[] getSelectedEvals() {
        return selectedEvals;
    }

    public void setSelectedEvals(EvaluacionDto[] selectedEvals) {
        this.selectedEvals = selectedEvals;
    }

    public List<EvaluacionDto> getListaEvaluaciones() {
        return listaEvaluaciones;
    }

    public void setListaEvaluaciones(List<EvaluacionDto> listaEvaluaciones) {
        this.listaEvaluaciones = listaEvaluaciones;
    }

    public ProcesoEvaluacionDto getProcesoEvaluacionDto() {
        return procesoEvaluacionDto;
    }

    public void setProcesoEvaluacionDto(ProcesoEvaluacionDto procesoEvaluacionDto) {
        this.procesoEvaluacionDto = procesoEvaluacionDto;
    }

    public SelectItem[] getSiTipoProceso() {
        return manager.siTipoProceso();
    }

    public void setSiTipoProceso(SelectItem[] siTipoProceso) {
        this.siTipoProceso = siTipoProceso;
    }

    public List<ProcesoEvaluacionDto> getListaProcesoEvaluacionAux() {
        if (!listaProcesoEvaluacionAux.isEmpty()) {
            UtilCore.General.ordena(listaProcesoEvaluacionAux, "orden");
        }
        return listaProcesoEvaluacionAux;
    }

    public void setListaProcesoEvaluacionAux(List<ProcesoEvaluacionDto> listaProcesoEvaluacionAux) {
        this.listaProcesoEvaluacionAux = listaProcesoEvaluacionAux;
    }

    public Long getIndeice() {
        return indeice;
    }

    public void setIndeice(Long indeice) {
        this.indeice = indeice;
    }

    public boolean isHabilitarEvaluacion() {
        return habilitarEvaluacion;
    }

    public void setHabilitarEvaluacion(boolean habilitarEvaluacion) {
        this.habilitarEvaluacion = habilitarEvaluacion;
    }
}
